﻿using ASmile.Com;
using ASmile.DBModel;
using ASmile.Extend;
using ASmile.Win.DaBLL;
using System.Collections.Generic;
using System.Windows.Forms;

namespace ASmile.Win
{
    /// <summary>
    /// 打印配置参数
    /// </summary>
    public class PrintReportArg
    {
        public PrintReportArg() { }

        public PrintReportArg(string reportName)
            : this(reportName, false)
        { }
        /// <summary>
        /// 创建打印参数，如果isNull== true，会隐藏该子报表
        /// </summary>
        public PrintReportArg(string reportName, bool isNull)
        {
            SubReportName = reportName;
            IsNullReport = isNull;
        }

        /// <summary>
        /// 报表名称，主报表为空
        /// </summary>
        public string SubReportName { set; get; }
        /// <summary>
        /// 是否续打
        /// </summary>
        public bool IsContinue { set; get; } = false;
        /// <summary>
        /// 续打时 - 开始行
        /// </summary>
        public int StartRow { set; get; }
        /// <summary>
        /// 续打时 - 结束行
        /// </summary>
        public int EndRow { set; get; }
        /// <summary>
        /// 续打时 - 列名
        /// </summary>
        public string[] ColumnNames { set; get; }
        /// <summary>
        /// 参数对象, 支持 class、Dictionary
        /// </summary>
        public object[] ParameterData { set; get; }
        /// <summary>
        /// 明细数据，支持 DataTable、IList、DataGridView
        /// </summary>
        public object DetailData { set; get; }
        /// <summary>
        /// 图片列表
        /// </summary>
        public Dictionary<string, byte[]> ImageList { set; get; }

        /// <summary>
        /// 子报表参数
        /// </summary>
        public List<PrintReportArg> SubReports { set; get; }
        /// <summary>
        /// 是否空报表，true时会将子报表可见为false
        /// </summary>
        public bool IsNullReport { get; set; }
    }

    /// <summary>
    /// 打印配置参数定义
    /// </summary>
    public class PrintConfigArg : PrintReportArg
    {
        /// <summary>
        /// 是否预览(false:直接打印)
        /// </summary>
        public bool IsPreview { set; get; }
        /// <summary>
        /// 打印时显示打印对话框(可选择打印机)
        /// </summary>
        public bool ShowPrintDialog { set; get; }
        /// <summary>
        /// 打印机名称
        /// </summary>
        public string PrinterName { set; get; }
        /// <summary>
        /// 打印模板文件
        /// </summary>
        public string TemplateFile { set; get; }

    }
    /// <summary>
    /// winform 打印接口定义
    /// </summary>
    public interface IPrint
    {
        void Print(PrintConfigArg config);

        Form GetPrintForm(PrintConfigArg config);

        void SetPrintArg(PrintConfigArg config);
    }
    /// <summary>
    /// 打印帮助类
    /// </summary>
    public static class PrintHelper
    {
        static PrintHelper()
        {
            PrintObj = ObjectFactory.GetObject<IPrint>("PrintCore");
            BLLObj = new PrintConfigBLL();
            LoginArg.Add("Sys_DeptName", LoginUser.DeptName);
            LoginArg.Add("Sys_UserName", LoginUser.UserName);
            LoginArg.Add("Sys_RoleName", LoginUser.RoleName);
        }

        public static IPrint PrintObj { get; }

        static IPrintConfigBLL BLLObj { get; } = ObjectFactory.GetObject<IPrintConfigBLL>("PrintConfigBLL");

        /// <summary>
        /// 登陆用户参数对象（当前用户名，当前科室，当前角色）
        /// </summary>
        static Dictionary<string, object> LoginArg { get; } = new Dictionary<string, object>();
        /// <summary>
        /// 按参数打印
        /// </summary>
        public static PrintConfigArg GetPrintArg(FrmBase form, PrintReportArg arg, int printIndex = 0)
        {
            if (form.PrintConfigs == null)
            {
                //是否应该缓存读取
                form.PrintConfigs = BLLObj.GetPrintConfigs(form.ContainerName).data;
                if (form.PrintConfigs == null) form.PrintConfigs = new List<Sys_PrintConfig>();
            }

            var config = form.PrintConfigs.Find(s => s.PrintIndex == printIndex);
            if (config == null) return null;
            if (config.TemplateFile.IsEmpty())
            {
                MessageBox.Show("未找到该窗体的打印模板");
                return null;
            }
            if (config.IsConfirm && !form.ShowQuestion($"是否要打印 {config.Caption} ?", "打印确认")) return null;

            PrintConfigArg configArg = new PrintConfigArg
            {
                TemplateFile = config.TemplateFile,
                IsPreview = config.IsPreview,
                PrinterName = config.PrinterName,
                ShowPrintDialog = config.ShowPrintDialog,
                IsContinue = arg.IsContinue,
                DetailData = arg.DetailData,
                ColumnNames = arg.ColumnNames,
                EndRow = arg.EndRow,
                ImageList = arg.ImageList,
                ParameterData = arg.ParameterData,
                StartRow = arg.StartRow,
                SubReportName = arg.SubReportName,
                SubReports = arg.SubReports
            };

            return configArg;
        }
        /// <summary>
        /// 获取打印窗体，用于嵌套报表中
        /// </summary>
        public static Form GetPrintForm(FrmBase form, PrintReportArg arg, int printIndex = 0)
        {
            var configArg = GetPrintArg(form, arg, printIndex);
            if (configArg == null) return null;
            var frm = PrintObj.GetPrintForm(configArg);
            return frm;
        }

        public static void SetPrintArg(FrmBase form, PrintReportArg arg, int printIndex = 0)
        {
            var configArg = GetPrintArg(form, arg, printIndex);
            if (configArg == null) return;
            PrintObj.SetPrintArg(configArg);
        }
        /// <summary>
        /// 按参数打印
        /// </summary>
        public static void Print(FrmBase form, PrintReportArg arg, int printIndex = 0)
        {
            var configArg = GetPrintArg(form, arg, printIndex);
            if (configArg == null) return;
            PrintObj.Print(configArg);
        }
        /// <summary>
        /// 打印
        /// </summary>
        public static void Print(FrmBase form, object detailData, object[] parameterData, int printIndex = 0)
        {
            object[] newParams;
            if (parameterData?.Length > 0)
            {
                newParams = new object[parameterData.Length + 1];
                parameterData.CopyTo(newParams, 0);
                newParams[newParams.Length - 1] = LoginArg;
            }
            else
            {
                newParams = new object[] { LoginArg };
            }
            PrintConfigArg arg = new PrintConfigArg
            {
                DetailData = detailData,
                ParameterData = newParams,
                IsContinue = false,
            };

            Print(form, arg, printIndex);
        }
    }
}